#include <microhttpd.h>
#include <open62541.h>
#include <sqlite3.h>
#include <string.h>
#include <modbus.h>
#include "cs104_connection.h"
#include "hal_time.h"
#include "hal_thread.h"
#include <cjson/cJSON.h>
//#include "SQLiteBackend.h"
#include <time.h>

#include "dlt645_2007_private.h"
#include "dlt645.h"
#include "dlt645_port.h"

//固件升级调用的头文件
#include <curl/curl.h>
//#include "open62541/server.h"
/*
模仿http请求，开辟专门的缓冲区去接收请求
同样开辟一个区域去接收sql的查询结果
*/
struct sql_query_result_object{
  /*OPC*/
  char id[16];//independ for each variable
  char name[64];
  char var_type[32];//uint32 uint16 int32 char
  //Purpose:after process for modbus instruct return value
  char protocol[16];//internal protocol
  //Purpose:only protocol relate attribute will be assign value
  /*OPC*/

  /*DL/T 645*/
  char dlt645_param[512];
  /*DL/T 645*/

  /*modbus RTU*/
  //128个字节不够，基本的例子就需要196个
  char rtu_param[256];
  /*modbus RTU*/

  /*modbus tcp*/
  char ip_address[32];
  int port;
  char register_type[32];//0:reg 1:coil
  int begin_address;
  int offset_range;
  /*modbus tcp*/

  /*DL/T 645*/
  /*
  when it needs to be used,it needs to be converted into a
  32-bit hexadecimal number
  */
  char specification[16];
  char reg_address[32];
  char data_field[256];
  // direction must be read
  /*DL/T 645*/

  /*IEC 104*/
  char iec_ip_address[32];
  int iec_port;
  char iec_typeid[32];
  char iec_cot[32];
  // int iec_begin_address;
  // int iec_offset_range;
  char iec_param[256];
  /*IEC 104*/
};

void updata_var_iec104();
void opc_ALL_var_name();

//新增OPC server上变量
//返回值为0，说明http传入的参数有异常
int OPC_addVariable(UA_Server *server,char* name,char * parm_protocol);
//在OPC client的请求到来时，根据底层参数去更新变量的值并返回
void OPC_Write_Value(UA_Server *server,char* var_name,UA_Variant client_parm);
void opc_public_add_var_finish_op(UA_Server *server,char* opc_var_name,UA_UInt32* values,int array_size,int opc_data_type);
//void opc_public_add_var_finish_op(UA_Server *server,char* opc_var_name,UA_UInt32* values,int array_size);

//void OPC_Write_Value(UA_Server *server,char* var_name);
/*
获取变量对应的底层协议的具体配置，比如DLT645使用的规范类型，modbus，IEC104的数据类型，起始地址
偏移量等一系列底层的参数，这些数据在新建变量的时候
*/
void sql_selet_get_var_protocol(char* name);

void sql_select_get_var_protocol_config(char* name);
void updateVariable(UA_Server *server,char* var_name);
void beforeReadTime(UA_Server *server,
               const UA_NodeId *sessionId, void *sessionContext,
               const UA_NodeId *nodeid, void *nodeContext,
               const UA_NumericRange *range, const UA_DataValue *data);
void afterWriteTime(UA_Server *server,
               const UA_NodeId *sessionId, void *sessionContext,
               const UA_NodeId *nodeId, void *nodeContext,
               const UA_NumericRange *range, const UA_DataValue *data);
int OPC_Modbus_tcp_Read();
//void OPC_Modbus_tcp_Read();

//void SQL_insert_opc_history_data(char* opc_var_name,char* opc_var_data,char* updata_time);
void SQL_insert_opc_history_data(char* opc_var_name,char* opc_var_data);
char* OPC_var_to_JSON(void* opc_val_array,int array_size,int format);
/*
IEC104内部使用的函数
*/
static void connectionHandler(void* parameter, CS104_Connection connection, CS104_ConnectionEvent event);
static bool asduReceivedHandler (void* parameter, int address, CS101_ASDU asdu);